package cn.scau.server.service.impl;

import cn.scau.server.mapper.ProcessNodeMapper;
import cn.scau.server.pojo.ProcessNode;
import cn.scau.server.service.ProcessNodeService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static cn.scau.server.utils.RedisConstants.CACHE_EXPIRE_TIME;
import static cn.scau.server.utils.RedisConstants.CACHE_KEY_PREFIX;

@Service
@Transactional
public class ProcessNodeServiceImpl extends ServiceImpl<ProcessNodeMapper, ProcessNode> implements ProcessNodeService {

    @Resource
    private StringRedisTemplate stringRedisTemplate; // 改为注入StringRedisTemplate

    @Resource
    private ObjectMapper objectMapper; // 用于JSON序列化

    public List<ProcessNode> getByFlowId(Integer processId) {
        // 构造缓存键
        String cacheKey = CACHE_KEY_PREFIX + processId;

        try {
            // 先从Redis中查询JSON字符串
            String jsonList = stringRedisTemplate.opsForValue().get(cacheKey);

            // 如果缓存存在则反序列化返回
            if (jsonList != null && !jsonList.isEmpty()) {
                return objectMapper.readValue(jsonList, new TypeReference<List<ProcessNode>>(){});
            }
        } catch (Exception e) {
            log.error("Redis缓存反序列化失败", e); // 实际项目中需要添加日志工具
        }

        // 缓存不存在则查询数据库
        QueryWrapper<ProcessNode> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("flow_id", processId);
        List<ProcessNode> list = list(queryWrapper);

        // 对查询结果排序
        list.sort(Comparator.comparing(ProcessNode::getNodePriority));

        try {
            // 序列化为JSON并存入Redis
            String jsonData = objectMapper.writeValueAsString(list);
            stringRedisTemplate.opsForValue().set(
                    cacheKey,
                    jsonData,
                    CACHE_EXPIRE_TIME,
                    TimeUnit.MINUTES
            );
        } catch (Exception e) {
            log.error("Redis缓存序列化失败", e);
        }

        return list;
    }

    @Override
    public Integer getInitStatus(Integer flowId) {
        //根据传来的流程类型，得到流程节点，然后最开始根据连着哪一步不用
        List<ProcessNode> list = getByFlowId(flowId);
        Integer status = 0;
        for (ProcessNode node : list) {
            if(node.getIsWithDept()){
                status = node.getNodePriority();
                break;
            }else{
                status = node.getNodePriority();
            }
        }

        return status;
    }

    @Override
    public Integer getRemainPriority(Integer flowId, Integer status) {
        List<ProcessNode> list = getByFlowId(flowId);
        int priority = 0;
        for (ProcessNode node : list) {
            if(node.getNodePriority().equals(status)){
                priority = node.getDeptPriority();
                break;
            }
        }
        return priority;
    }

    @Override
    public Integer getNextStatus(Integer status, Integer flowId) {
        List<ProcessNode> originalList = getByFlowId(flowId);
        List<ProcessNode> newList = new ArrayList<>(originalList); // 创建一个新的 List 拷贝

        ProcessNode virtualNode = new ProcessNode();
        virtualNode.setNodePriority(getFinalStatus(flowId));
        virtualNode.setIsWithDept(false);
        virtualNode.setNodeName("审核完成");
        newList.add(virtualNode); // 在新 List 中添加虚拟节点

        Integer initStatus = status;
        for (ProcessNode node : newList) {
            if (node.getNodePriority() > status) {
                if (node.getIsWithDept()) {
                    initStatus = node.getNodePriority();
                    break;
                } else {
                    initStatus = node.getNodePriority();
                }
            }
        }
        return initStatus;
    }

    @Override
    public Integer getFinalStatus(Integer flowId) {
        //创造虚拟尾节点，用作逻辑判断是不是最后一个节点真的走完了
        List<ProcessNode> list = getByFlowId(flowId);
        ProcessNode processNode = list.get(list.size() - 1);
        return processNode.getNodePriority()+1;
    }

    @Override
    public String getStatusName(Integer flowId, Integer status) {
        List<ProcessNode> list = getByFlowId(flowId);
        String statusName = "";
        for(ProcessNode node : list){
            if(node.getNodePriority().equals(status)){
                statusName = node.getNodeName();
                break;
            }
        }
        return statusName;
    }

    @Override
    public boolean isLastStatus(Integer status, Integer flowId) {
        Integer finalStatus = getFinalStatus(flowId);
        return finalStatus.equals(status);
    }

}
